from ruamel.yaml import YAML

def flatten_dict(d, parent_key=''):
    """
    递归展开字典，将嵌套的键合并为用点分隔的形式，同时获取可能的 inline 注释。
    返回一个字典，键为展开后的参数名称，值为 (value, desc) 二元组。
    """
    items = {}
    for k, v in d.items():
        # 展开键的名称
        new_key = f"{parent_key}.{k}" if parent_key else k

        # 尝试获取该键对应的 inline 注释
        desc = ""
        if hasattr(d, 'ca') and k in d.ca.items:
            comment_tuple = d.ca.items[k]
            # 注释一般存放在第三个元素（索引 2），可能为 None
            if len(comment_tuple) > 2 and comment_tuple[2] is not None:
                inline_comment = comment_tuple[2]
                if hasattr(inline_comment, 'value'):
                    desc = inline_comment.value.strip()
                else:
                    desc = str(inline_comment).strip()
                if desc.startswith('#'):
                    desc = desc.lstrip('#').strip()

        # 如果值为字典，则递归展开；否则保存当前项
        if isinstance(v, dict):
            nested_items = flatten_dict(v, new_key)
            items.update(nested_items)
        else:
            items[new_key] = (v, desc)
    return items

def map_type(default):
    """
    根据 Python 默认值映射到 C++ 对应的类型字符串。
    """
    if isinstance(default, bool):
        return "bool"
    elif isinstance(default, int):
        return "int"
    elif isinstance(default, float):
        return "float"
    elif isinstance(default, str):
        return "std::string"
    else:
        return "auto"  # 其他类型暂用 auto

def format_default_value(default):
    """
    根据不同类型格式化默认值输出
    如果是字符串，则加上双引号，
    如果是布尔值，则转换为小写字符串。
    """
    if isinstance(default, str):
        return f'"{default}"'
    elif isinstance(default, bool):
        return "true" if default else "false"
    else:
        return str(default)

def parse_parameters_file(file_path):
    """
    解析参数 YAML 文件，查找 /monitor 下 ros__parameters 部分，
    将参数展开为平铺的形式，生成字符串：
      Param<TYPE>("parameter_name", default_value, "desc")
    其中 TYPE 为映射后的 C++ 支持类型，如 int, std::string, float, bool 等。
    """
    parameters = []
    yaml = YAML(typ='rt')  # 保留注释
    with open(file_path, 'r') as f:
        config = yaml.load(f)

    # 查找顶层键是 "/monitor" 的部分，并提取 ros__parameters
    parameters_section = {}
    for root_key, root_value in config.items():
        if isinstance(root_value, dict) and 'ros__parameters' in root_value:
            parameters_section = root_value['ros__parameters']
            break

    # 展开嵌套字典，获取每个参数的值和注释
    flat_params = flatten_dict(parameters_section)
    for name, (default, desc) in flat_params.items():
        cpp_type = map_type(default)
        default_str = format_default_value(default)
        parameters.append(f'Param<{cpp_type}>("{name}", {default_str}, "{desc}")')
    return parameters

if __name__ == '__main__':
    file_path = "parameters.yaml"  # 请将此处修改为你的 YAML 文件路径
    params = parse_parameters_file(file_path)
    for param in params:
        print(param)
